home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / jabber / filetransfer / S5BFileXferHandler.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  10KB  |  239 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from jabber.objects.si_filetransfer import SI_FileTransfer
  5. from util.Events import EventMixin
  6. from pyxmpp.expdict import ExpiringDictionary
  7. from common.timeoutsocket import TimeoutSocketMulti
  8. from util.net import SocketEventMixin
  9. import common
  10. import util
  11. from struct import pack, unpack
  12. from functools import partial
  13. from jabber.objects.si import SI_NS
  14. from jabber.objects.bytestreams import BYTESTREAMS_NS, ByteStreams
  15. from hashlib import sha1
  16. from pyxmpp.jid import JID
  17. from pyxmpp.iq import Iq
  18. import logging
  19.  
  20. class ProxyFailure(StopIteration):
  21.     pass
  22.  
  23.  
  24. class ByteStream(EventMixin):
  25.     events = EventMixin.events | set(('stream_connected', 'stream_connect_failed', 'stream_rejected', 'stream_data_recieved', 'stream_closed', 'stream_error'))
  26.  
  27.  
  28. class INByteStream(ByteStream):
  29.     
  30.     def __init__(self, si_ft, jabber_protocol):
  31.         ByteStream.__init__(self)
  32.         self.si_ft = si_ft
  33.         self.j = jabber_protocol
  34.  
  35.  
  36.  
  37. class SOCKS5Bytestream(INByteStream):
  38.     log = logging.getLogger('jabber.filetrans.s5bxferhandler')
  39.     
  40.     def accept_stream(self, hosts_bytestreams, from_, to_, id):
  41.         self.from_ = from_
  42.         self.to_ = to_
  43.         self.respond_id = id
  44.         self.hosts_bytestreams = hosts_bytestreams
  45.         self.my_sock = S5BOutgoingSocket(hosts_bytestreams, from_, to_)
  46.         self.my_sock.bind_event('connected', self.on_succ)
  47.         self.my_sock.bind_event('connection_failed', self.on_fail)
  48.         self.my_sock.get_connect()
  49.  
  50.     
  51.     def on_fail(self):
  52.         self.log.warning('S5BFileXferHandler connect failed')
  53.         i = Iq(to_jid = self.from_, from_jid = self.to_, stanza_type = 'error', stanza_id = self.respond_id, error_cond = u'item-not-found')
  54.         self.j.send(i)
  55.         self.event('stream_connect_failed')
  56.  
  57.     
  58.     def on_succ(self, num_tries_taken, sock):
  59.         host_used = self.hosts_bytestreams.hosts[num_tries_taken - 1].jid
  60.         self.my_sock = sock
  61.         i2 = Iq(to_jid = self.from_, stanza_type = 'result', stanza_id = self.respond_id)
  62.         b = ByteStreams()
  63.         b.host_used = JID(host_used)
  64.         b.as_xml(i2.get_node())
  65.         self.my_sock.found_terminator = self.close
  66.         self.my_sock.collect_incoming_data = self.collect_incoming_data
  67.         self.my_sock.set_terminator(self.si_ft.file.size)
  68.         self.my_sock.bind_event('socket_closed', self.closed)
  69.         self.my_sock.bind_event('socket_error', self.stream_error)
  70.         self.j.send(i2)
  71.         self.log.info('S5BFileXferHandler connect succeeded to %s', host_used)
  72.         self.event('stream_connected')
  73.  
  74.     
  75.     def stream_error(self):
  76.         self.event('stream_error')
  77.         self.unbind_all()
  78.  
  79.     
  80.     def collect_incoming_data(self, data):
  81.         self.event('stream_data_recieved', data)
  82.  
  83.     
  84.     def close(self):
  85.         
  86.         try:
  87.             self.my_sock.close()
  88.         except:
  89.             pass
  90.  
  91.         self.closed()
  92.  
  93.     
  94.     def timed_out(self):
  95.         self.event('stream_connect_failed')
  96.         self.close()
  97.  
  98.     
  99.     def closed(self):
  100.         self.event('stream_closed')
  101.         self.unbind_all()
  102.  
  103.     
  104.     def unbind_all(self):
  105.         if hasattr(self, 'my_sock'):
  106.             self.my_sock.unbind('connected', self.on_succ)
  107.             self.my_sock.unbind('connection_failed', self.on_fail)
  108.             self.my_sock.unbind('socket_closed', self.closed)
  109.             self.my_sock.unbind('socket_error', self.stream_error)
  110.         
  111.  
  112.  
  113.  
  114. class S5BRecvHandler(object):
  115.     
  116.     def __init__(self, j):
  117.         self.d = ExpiringDictionary(60)
  118.         self.j = j
  119.  
  120.     
  121.     def register_handlers(self):
  122.         self.j.stream.set_iq_set_handler('query', BYTESTREAMS_NS, self.handleSI)
  123.         self.j.idle_loop += self.d.expire
  124.  
  125.     
  126.     def handleSI(self, stanza):
  127.         print 'handleSI called'
  128.         b = ByteStreams(stanza.get_query())
  129.         sid = b.sid
  130.         if sid in self.d:
  131.             self.d[sid].accept_stream(b, stanza.get_from(), stanza.get_to(), stanza.get_id())
  132.             return True
  133.         else:
  134.             return False
  135.  
  136.     
  137.     def waitfor(self, stanza):
  138.         si_ft = SI_FileTransfer(stanza.xpath_eval('si:si', {
  139.             'si': SI_NS })[0])
  140.         print 'waiting for stream for ', si_ft
  141.         s5b = SOCKS5Bytestream(si_ft, self.j)
  142.         self.d.set_item(si_ft.sid, s5b, timeout_callback = s5b.timed_out)
  143.         return s5b
  144.  
  145.     __call__ = waitfor
  146.  
  147.  
  148. class S5BOutgoingSocketOne(common.TimeoutSocketOne, SocketEventMixin):
  149.     
  150.     def __init__(self, *a, **k):
  151.         SocketEventMixin.__init__(self)
  152.         common.TimeoutSocketOne.__init__(self, *a, **k)
  153.  
  154.     
  155.     def succ(self):
  156.         self.proc(self.s5b_ok())
  157.  
  158.     
  159.     def s5b_ok(self):
  160.         yield (2, pack('BBB', 5, 1, 0))
  161.         ok = None
  162.         (_head, authmethod) = unpack('BB', ok)
  163.         if authmethod != 0:
  164.             raise ProxyFailure()
  165.         
  166.         out = pack('!BBBBB40sH', 5, 1, 0, 3, 40, self.hash, 0)
  167.         in_fmt = ('!BBBB', 's5head', 'status', 'reserved', 'addrtype')
  168.         yield (4, out)
  169.         in_ = None
  170.         head = util.unpack_named(*in_fmt + (in_,))
  171.         if head.addrtype == 3:
  172.             yield (1, '')
  173.             head.addrlen = None
  174.             head.addrlen = ord(head.addrlen)
  175.             if head.addrlen > 0:
  176.                 yield (head.addrlen, '')
  177.                 address = None
  178.             else:
  179.                 address = ''
  180.         
  181.         yield (2, '')
  182.         _port = None
  183.         if head.status != 0:
  184.             raise ProxyFailure()
  185.         
  186.  
  187.     
  188.     def proc(self, gen):
  189.         
  190.         try:
  191.             (to_read, out_bytes) = gen.send(self.data)
  192.         except ProxyFailure:
  193.             return self.do_fail()
  194.         except StopIteration:
  195.             return common.TimeoutSocketOne.succ(self)
  196.  
  197.         bytes = str(out_bytes)
  198.         if out_bytes:
  199.             self.push(bytes)
  200.         
  201.         self.data = ''
  202.         self.found_terminator = partial(self.proc, gen)
  203.         if isinstance(to_read, int):
  204.             self.set_terminator(to_read)
  205.         else:
  206.             self.set_terminator(to_read._size())
  207.  
  208.  
  209.  
  210. class S5BOutgoingSocket(SocketEventMixin):
  211.     
  212.     def __init__(self, hosts_bytestreams, from_, to_):
  213.         SocketEventMixin.__init__(self)
  214.         self.log = logging.getLogger('S5BOutgoingSocket')
  215.         self.log.warning('S5BOutgoingSocket')
  216.         shosts = hosts_bytestreams.hosts
  217.         self.addys = [ (host.host, host.port) for host in shosts ]
  218.         self.sid = hosts_bytestreams.sid
  219.         self.hash = sha1(self.sid + from_.as_utf8() + to_.as_utf8()).hexdigest()
  220.         self.t = TimeoutSocketMulti()
  221.         
  222.         self._on_failure = lambda : self.event('connection_failed')
  223.  
  224.     
  225.     def provide_data(self, sock):
  226.         sock.hash = self.hash
  227.  
  228.     
  229.     def connected(self, sock):
  230.         sock.reassign()
  231.         self.sock = sock
  232.         self.event('connected', self.t.attempts, sock)
  233.  
  234.     
  235.     def get_connect(self):
  236.         self.t.tryconnect(self.addys, self.connected, self._on_failure, 2, cls = S5BOutgoingSocketOne, provide_init = self.provide_data)
  237.  
  238.  
  239.